// 全局变量
let isRunning = false;
let currentPage = 1;
let totalPages = 0;
let scrollDelay = 1500;
let scrapedData = [];
let apiRequests = new Set(); // 存储已处理的API URL
let capturedApiUrls = new Set(); // 存储捕获到的API URL
let lastScrollTime = 0; // 记录最后一次滚动时间
let targetApiPattern = 'search_videos'; // 目标API模式，只匹配关键部分
let processedPages = new Set(); // 存储已处理的页码，防止重复
let debugMode = false; // 调试模式，默认关闭
let scrollCount = 0; // 滚动计数器
let maxScrollAttempts = 100; // 增大最大滚动尝试次数，防止提前终止
let isScrolling = false; // 是否正在滚动中，防止重复滚动
let lastAnalyzeTime = 0; // 上次分析网络请求的时间
let noNewPageCount = 0; // 新增：重置无新分页请求计数器
const NO_NEW_PAGE_LIMIT = 15; // 增大无新分页请求判定阈值
let hasExported = false; // 防止重复导出
let lastScrollHeight = 0; // 记录上一次页面高度
let noContentGrowCount = 0; // 连续页面高度未增长计数
const NO_CONTENT_GROW_LIMIT = 5; // 连续未增长阈值
let hasNewPageThisRound = false;
let scrollResolve = null;

// 监听来自popup的消息
chrome.runtime.onMessage.addListener(function(request, sender, sendResponse) {
  if (request.action === 'startScraping') {
    // 开始爬取
    isRunning = true;
    scrollCount = 0; // 重置滚动计数器
    isScrolling = false; // 重置滚动状态
    lastAnalyzeTime = 0; // 重置分析时间
    noNewPageCount = 0; // 新增：重置无新分页请求计数器
    
    // 检查是否有已保存的页码，如果没有则从第1页开始
    chrome.storage.local.get(['currentPage', 'scrapedData', 'processedPages'], function(result) {
      if (result.currentPage && result.scrapedData && result.scrapedData.length > 0) {
        currentPage = result.currentPage;
        scrapedData = result.scrapedData || [];
        processedPages = new Set(result.processedPages || []);
        console.log(`继续从第 ${currentPage} 页爬取，已处理页码: ${Array.from(processedPages).join(', ')}`);
      } else {
        currentPage = 1;
        scrapedData = [];
        processedPages = new Set();
      }
      scrollDelay = request.scrollDelay || 1500;
      apiRequests = new Set();
      capturedApiUrls = new Set();
      lastScrollTime = 0;
      
      // 保存初始状态到storage
      chrome.storage.local.set({
        isRunning: true,
        currentPage: currentPage,
        videoCount: scrapedData.length,
        scrapedData: scrapedData,
        processedPages: Array.from(processedPages)
      });
      
      // 开始爬取
      startScraping();
      sendResponse({status: 'started'});
    });
    
    return true; // 保持消息通道开放，以便异步发送响应
  } 
  else if (request.action === 'stopScraping') {
    // 停止爬取
    isRunning = false;
    sendResponse({status: 'stopped'});
  }
  else if (request.action === 'resetScraping') {
    // 重置爬取状态
    isRunning = false;
    currentPage = 1;
    scrapedData = [];
    processedPages = new Set();
    scrollCount = 0;
    isScrolling = false;
    lastAnalyzeTime = 0;
    noNewPageCount = 0;
    hasExported = false;
    apiRequests = new Set(); // 清理已处理的API请求记录
    capturedApiUrls = new Set(); // 清理捕获的API URL记录
    scrollResolve = null; // 清理滚动Promise
    
    chrome.storage.local.set({
      isRunning: false,
      currentPage: 1,
      videoCount: 0,
      scrapedData: [],
      processedPages: []
    }, function() {
      console.log('爬取状态已重置，所有缓存已清理');
      sendResponse({status: 'reset'});
    });
    
    return true;
  }
  else if (request.action === 'checkLoginStatus') {
    // 检查登录状态
    checkLoginStatus().then(loggedIn => {
      sendResponse({loggedIn: loggedIn});
    });
    return true;
  }
  else if (request.action === 'checkStatus') {
    // 检查当前状态
    const statusData = {
      currentPage: currentPage,
      processedPages: Array.from(processedPages).sort((a, b) => a - b),
      capturedApiUrls: capturedApiUrls.size,
      apiRequests: apiRequests.size,
      scrapedDataCount: scrapedData.length,
      isRunning: isRunning,
      scrollCount: scrollCount,
      noNewPageCount: noNewPageCount
    };
    sendResponse({status: 'success', data: statusData});
    return true;
  }
  else if (request.action === 'analyzeNetworkRequests') {
    // 分析网络请求
    analyzeNetworkRequests().then(result => {
      sendResponse(result);
    });
    return true;
  }
  else if (request.action === 'exportJSON') {
    // 导出JSON数据
    chrome.storage.local.get(['scrapedData'], function(result) {
      if (result.scrapedData && result.scrapedData.length > 0) {
        sendResponse({
          success: true,
          data: result.scrapedData
        });
      } else {
        sendResponse({
          success: false,
          message: '没有可导出的数据'
        });
      }
    });
    return true;
  }
  else if (request.action === 'fixPageNumbers') {
    // 修复页码问题
    chrome.storage.local.get(['scrapedData'], function(result) {
      if (result.scrapedData && result.scrapedData.length > 0) {
        const fixedData = fixPageNumbers(result.scrapedData);
        // 保存修复后的数据
        chrome.storage.local.set({
          scrapedData: fixedData
        }, function() {
          exportToJSON(fixedData);
          sendResponse({
            success: true,
            message: `已修复页码并导出 ${fixedData.length} 条数据`
          });
        });
      } else {
        sendResponse({
          success: false,
          message: '没有可修复的数据'
        });
      }
    });
    return true;
  }
  
  return true;
});

// 检查登录状态
async function checkLoginStatus() {
  console.log('开始检查登录状态...');
  
  try {
    // 尝试访问指定URL，如果返回200状态码则认为已登录
    const targetUrl = 'https://buyin.jinritemai.com/dashboard/inspiration-center/hot-video';
    console.log('尝试请求目标URL:', targetUrl);
    
    const response = await fetch(targetUrl, {
      method: 'GET',
      credentials: 'include',
      headers: {
        'Accept': 'text/html,application/xhtml+xml,application/xml',
        'Cache-Control': 'no-cache'
      },
      redirect: 'follow'
    });
    
    console.log('请求状态码:', response.status);
    console.log('请求URL:', response.url);
    
    // 如果返回200状态码，或者没有重定向到登录页面，则认为已登录
    const isLoggedIn = response.status === 200 && !response.url.includes('/login');
    console.log('登录状态:', isLoggedIn ? '已登录' : '未登录');
    
    return isLoggedIn;
  } catch (error) {
    console.error('检查登录状态出错:', error);
    return false;
  }
}

// 开始爬取
function startScraping() {
  if (!isRunning) return;
  hasExported = false; // 重置导出标志
  setupNetworkInterceptor();
  setupScrollListener();
  stableScrollLoop();
}

// 设置滚动事件监听
function setupScrollListener() {
  console.log('设置滚动事件监听');
  
  // 移除可能存在的旧监听器
  window.removeEventListener('scroll', onPageScroll);
  
  // 添加新的监听器
  window.addEventListener('scroll', onPageScroll);
}

// 滚动事件处理函数
function onPageScroll(event) {
  if (!isRunning) return;
  
  // 记录滚动时间
  lastScrollTime = Date.now();
  
  // 检查是否滚动到底部
  const scrollHeight = document.documentElement.scrollHeight;
  const scrollTop = document.documentElement.scrollTop || document.body.scrollTop;
  const clientHeight = document.documentElement.clientHeight;
  
  // 如果滚动到页面底部附近
  if (scrollTop + clientHeight >= scrollHeight - 200) {
    console.log('检测到滚动到页面底部，可能触发加载更多');
    
    // 延迟一段时间后检查新的网络请求
    setTimeout(() => {
      if (isRunning) {
        analyzeNetworkRequests();
      }
    }, 1000); // 等待1秒，给API请求时间
  }
}

function stableScrollLoop() {
  if (!isRunning) return;
  hasNewPageThisRound = false;
  window.scrollTo(0, document.body.scrollHeight);
  lastScrollTime = Date.now();
  scrollCount++;
  console.log(`模拟滚动页面 (${scrollCount})，当前页码：${currentPage}`);

  // 等待API响应或超时
  return new Promise((resolve) => {
    scrollResolve = resolve;
    setTimeout(() => {
      if (scrollResolve) {
        scrollResolve(false); // 超时
        scrollResolve = null;
      }
    }, 3500); // 最多等3.5秒
  }).then((hasNewPage) => {
    if (hasNewPage) {
      noNewPageCount = 0;
    } else {
      noNewPageCount++;
      console.log('无新分页数据，noNewPageCount=' + noNewPageCount);
    }
    if (!isRunning) return;
    if (noNewPageCount >= NO_NEW_PAGE_LIMIT) {
      console.log('连续无新分页请求达到上限，判定为到底，停止爬取并导出');
      isRunning = false;
      if (scrapedData.length > 0 && !hasExported) {
        hasExported = true;
        setTimeout(() => {
          exportToJSON(scrapedData);
        }, 2000);
      }
      return;
    }
    setTimeout(stableScrollLoop, scrollDelay);
  });
}

// 分析网络请求，查找可能的API
async function analyzeNetworkRequests() {
  // 不打印普通日志，减少输出
  if (debugMode) {
    console.log('分析网络请求，查找目标API');
  }
  
  // 防止频繁分析，使用滚动延迟的四分之一作为最小间隔
  const currentTime = Date.now();
  const minAnalyzeInterval = Math.max(scrollDelay / 4, 500); // 至少500ms
  if (currentTime - lastAnalyzeTime < minAnalyzeInterval) {
    return;
  }
  lastAnalyzeTime = currentTime;
  
  if (debugMode) {
    // 在调试模式下，打印所有最近的网络请求
    const entries = performance.getEntriesByType('resource');
    console.log('当前页面所有网络请求:', entries.map(e => e.name).join('\n'));
    
    // 查找可能的API请求
    const possibleApis = entries.filter(e => e.name.includes('api') || e.name.includes('search'));
    console.log('可能的API请求:', possibleApis.map(e => e.name).join('\n'));
  }
  
  // 创建一个性能观察器
  const observer = new PerformanceObserver((list) => {
    const entries = list.getEntries();
    
    entries.forEach(entry => {
      const url = entry.name;
      
      // 只在调试模式下打印所有请求
      if (debugMode) {
        console.log('捕获到网络请求:', url);
      }
      
      // 检查是否是目标API
      if (url.includes(targetApiPattern)) {
        // 只打印目标API相关的日志
        console.log('发现目标API:', url);
        
        // 检查是否已经处理过这个URL
        if (capturedApiUrls.has(url)) {
          if (debugMode) {
            console.log('该API URL已处理过，跳过:', url);
          }
          return;
        }
        
        capturedApiUrls.add(url);
        
        // 主动获取API数据
        console.log('主动请求API数据:', url);
        fetch(url, {
          method: 'GET',
          credentials: 'include',
          headers: {
            'Accept': 'application/json',
            'Content-Type': 'application/json'
          }
        })
        .then(response => response.json())
        .then(data => {
          console.log('获取到API响应数据');
          processApiResponse(url, data);
        })
        .catch(error => {
          console.error('请求API数据失败:', error);
        });
      }
    });
  });
  
  // 开始观察资源加载性能
  observer.observe({ entryTypes: ['resource'] });
  
  // 返回当前捕获的API URL
  return {
    capturedApis: Array.from(capturedApiUrls)
  };
}

// 设置网络请求拦截器
function setupNetworkInterceptor() {
  // 只在调试模式下打印
  if (debugMode) {
    console.log('设置网络请求拦截器');
  }
  
  // 使用Chrome扩展API拦截网络请求
  const originalFetch = window.fetch;
  
  window.fetch = async function(input, init) {
    const response = await originalFetch.apply(this, arguments);
    
    try {
      // 检查是否是目标API
      if (input && typeof input === 'string') {
        // 只在调试模式下打印所有请求
        if (debugMode) {
          console.log('拦截到fetch请求:', input);
        }
        
        if (input.includes(targetApiPattern)) {
          console.log('拦截到目标API请求:', input);
          
          // 检查是否是在最近滚动后触发的请求
          const isTriggeredByScroll = Date.now() - lastScrollTime < 5000; // 5秒内的请求可能与滚动相关
          
          // 避免重复处理同一请求
          if (apiRequests.has(input)) {
            console.log('该请求已处理过，跳过');
            return response;
          }
          
          apiRequests.add(input);
          
          // 克隆响应以便我们可以使用它两次
          try {
            const responseClone = response.clone();
            
            // 处理响应
            responseClone.json().then(data => {
              console.log('成功解析API响应JSON');
              processApiResponse(input, data);
            }).catch(err => {
              console.error('处理API响应出错:', err);
            });
          } catch (error) {
            console.error('克隆响应出错:', error);
          }
        }
      }
    } catch (error) {
      console.error('拦截请求出错:', error);
    }
    
    return response;
  };
  
  // 监听XHR请求
  const originalXhrOpen = XMLHttpRequest.prototype.open;
  const originalXhrSend = XMLHttpRequest.prototype.send;
  
  XMLHttpRequest.prototype.open = function(method, url) {
    this._url = url;
    return originalXhrOpen.apply(this, arguments);
  };
  
  XMLHttpRequest.prototype.send = function() {
    if (this._url && typeof this._url === 'string') {
      // 只在调试模式下打印所有请求
      if (debugMode) {
        console.log('拦截到XHR请求:', this._url);
      }
      
      if (this._url.includes(targetApiPattern)) {
        console.log('拦截到XHR目标API请求:', this._url);
        
        // 检查是否是在最近滚动后触发的请求
        const isTriggeredByScroll = Date.now() - lastScrollTime < 5000; // 5秒内的请求可能与滚动相关
        
        const originalOnReadyStateChange = this.onreadystatechange;
        
        this.onreadystatechange = function() {
          if (this.readyState === 4 && this.status === 200) {
            try {
              // 避免重复处理同一请求
              if (apiRequests.has(this._url)) {
                console.log('该XHR请求已处理过，跳过');
                return;
              }
              
              apiRequests.add(this._url);
              
              const data = JSON.parse(this.responseText);
              console.log('成功解析XHR响应JSON');
              processApiResponse(this._url, data);
            } catch (error) {
              console.error('处理XHR响应出错:', error);
            }
          }
          
          if (originalOnReadyStateChange) {
            originalOnReadyStateChange.apply(this, arguments);
          }
        };
      }
    }
    
    return originalXhrSend.apply(this, arguments);
  };
  
  // 添加额外的网络监听
  if (window.chrome && chrome.webRequest && chrome.webRequest.onCompleted) {
    chrome.webRequest.onCompleted.addListener(
      function(details) {
        if (details.url.includes(targetApiPattern)) {
          console.log('通过chrome.webRequest捕获到目标API:', details.url);
          // 这里不能直接获取响应内容，但可以记录URL
          capturedApiUrls.add(details.url);
        }
      },
      {urls: ["<all_urls>"]}
    );
  }
}

// 修复页码问题
function fixPageNumbers(data) {
  console.log("开始修复页码...");
  
  // 检查数据中是否已经有页码
  const hasPageNumbers = data.some(item => item.page !== undefined);
  console.log(`数据中${hasPageNumbers ? '已有' : '没有'}页码标记`);
  
  // 尝试从URL中提取页码
  data.forEach((item, index) => {
    try {
      if (!item.page && item.url) {
        const urlObj = new URL(item.url, window.location.origin);
        const pageParam = urlObj.searchParams.get('page');
        if (pageParam) {
          const page = parseInt(pageParam);
          if (!isNaN(page)) {
            console.log(`为数据项 ${index} 从URL设置页码: ${page}`);
            item.page = page;
          }
        }
      }
    } catch (e) {
      console.error(`解析URL获取页码出错:`, e);
    }
  });
  
  // 统计数据中的页码分布
  const pageDistribution = {};
  data.forEach(item => {
    const page = item.page || 'unknown';
    pageDistribution[page] = (pageDistribution[page] || 0) + 1;
  });
  
  console.log("页码分布统计:", pageDistribution);
  
  // 对于没有页码的数据，根据顺序设置
  let currentAssignedPage = 1;
  let itemsInCurrentPage = 0;
  const maxItemsPerPage = 10; // 假设每页最多10条数据
  
  data.forEach((item, index) => {
    if (!item.page) {
      // 如果当前页已满，移到下一页
      if (itemsInCurrentPage >= maxItemsPerPage) {
        currentAssignedPage++;
        itemsInCurrentPage = 0;
      }
      
      console.log(`为数据项 ${index} 分配页码: ${currentAssignedPage}`);
      item.page = currentAssignedPage;
      itemsInCurrentPage++;
    }
  });
  
  // 最后再次统计
  const finalPageDistribution = {};
  data.forEach(item => {
    const page = item.page || 'unknown';
    finalPageDistribution[page] = (finalPageDistribution[page] || 0) + 1;
  });
  
  console.log("修复后页码分布:", finalPageDistribution);
  
  return data;
}

// 处理API响应
function processApiResponse(url, data) {
  if (!isRunning) {
    console.log('爬取已停止，不处理响应');
    return;
  }
  if (!url.includes(targetApiPattern)) {
    console.log('不是目标API，跳过处理');
    return;
  }
  
  console.log('处理目标API响应:', url);
  let page = currentPage;
  let isNewPage = false;
  try {
    const urlObj = new URL(url, window.location.origin);
    page = parseInt(urlObj.searchParams.get('page')) || currentPage;
    console.log('从URL提取的页码:', page);
    if (!processedPages.has(page)) {
      isNewPage = true;
      processedPages.add(page);
      if (page > currentPage) {
        currentPage = page;
        console.log(`更新当前页码为 ${currentPage}`);
      }
    }
  } catch (e) {
    console.log('无法从URL提取页码，使用当前页码:', currentPage);
  }
  if (!data || (data.status_code !== undefined && data.status_code !== 0)) {
    console.log('API响应数据无效，跳过处理');
    return;
  }
  if (isNewPage) {
    hasNewPageThisRound = true;
    if (scrollResolve) {
      scrollResolve(true); // 唤醒滚动主循环，表示有新分页
      scrollResolve = null;
    }
    noNewPageCount = 0;
  } else {
    // 不在这里递增 noNewPageCount，由主循环控制
    console.log(`无新分页数据，noNewPageCount=${noNewPageCount}`);
  }
  
  const originalData = {
    url: url,
    timestamp: new Date().toISOString(),
    page: page,
    data: data
  };
  scrapedData.push(originalData);
  chrome.storage.local.set({
    scrapedData: scrapedData,
    currentPage: currentPage,
    videoCount: scrapedData.length,
    processedPages: Array.from(processedPages)
  }, function() {
    console.log(`数据已保存到存储，当前共 ${scrapedData.length} 条数据，页码: ${page}`);
  });
  console.log(`已爬取第 ${page} 页数据，总计 ${scrapedData.length} 条`);
  // 防止重复导出
  if (!isRunning && scrapedData.length > 0 && !hasExported) {
    hasExported = true;
    exportToJSON(scrapedData);
  }
}

// 递归查找所有可能的视频数组，要求典型视频字段至少3个
function findAllVideoArraysStrict(obj, path = '') {
  let arrays = [];
  if (Array.isArray(obj) && obj.length > 0 && typeof obj[0] === 'object') {
    const sample = obj[0];
    let fieldCount = 0;
    if (sample.video_id || sample.id) fieldCount++;
    if (sample.title || sample.desc) fieldCount++;
    if (sample.author || sample.nickname || sample.author_name) fieldCount++;
    if (sample.cover || sample.video_cover || sample.thumbnail) fieldCount++;
    if (sample.like_count || sample.likes) fieldCount++;
    if (fieldCount >= 3) {
      arrays.push({ path, array: obj });
    }
  }
  if (typeof obj === 'object' && obj !== null) {
    for (const key in obj) {
      if (typeof obj[key] === 'object' && obj[key] !== null) {
        const newPath = path ? `${path}.${key}` : key;
        arrays = arrays.concat(findAllVideoArraysStrict(obj[key], newPath));
      }
    }
  }
  return arrays;
}

// 导出JSON文件
function exportToJSON(data) {
  console.log("开始导出JSON数据...", data.length);
  try {
    // 先修复数据中的页码问题
    const fixedData = fixPageNumbers(data);
    
    // 检测重复数据
    const urlSet = new Set();
    const duplicateUrls = [];
    fixedData.forEach((item, index) => {
      if (item.url) {
        if (urlSet.has(item.url)) {
          duplicateUrls.push({ index, url: item.url, page: item.page });
        } else {
          urlSet.add(item.url);
        }
      }
    });
    
    if (duplicateUrls.length > 0) {
      console.warn(`发现 ${duplicateUrls.length} 个重复的API请求:`);
      duplicateUrls.forEach(dup => {
        console.warn(`  索引 ${dup.index}: 页码 ${dup.page}, URL: ${dup.url}`);
      });
    } else {
      console.log("未发现重复的API请求，数据去重成功");
    }
    
    // 提取所有页面的video_list数据
    const allVideoList = [];
    const pageStats = {};
    const allPages = new Set();
    fixedData.forEach(item => { if (item.page) allPages.add(item.page); });
    console.log(`数据中包含的所有页码: ${Array.from(allPages).sort((a, b) => a - b).join(', ')}`);
    fixedData.forEach((pageData, index) => {
      try {
        const page = pageData.page || "未知";
        if (!pageStats[page]) pageStats[page] = { total: 0, extracted: 0 };
        pageStats[page].total++;
        // 只保留直接读取 data.data.video_list
        let videoArr = null;
        if (pageData.data && Array.isArray(pageData.data.data.video_list)) {
          videoArr = pageData.data.data.video_list;
          console.log(`页码 ${page} 直接使用 data.data.video_list, 共 ${videoArr.length} 条`);
        }
        if (videoArr && videoArr.length > 0) {
          videoArr.forEach(item => {
            const videoObj = {
              page: page,
              author_info: {
                nick_name: item.author || item.nickname || item.author_name || (item.author_info && item.author_info.nick_name) || '',
                fans_num: item.fans_count || item.fans_num || (item.author_info && item.author_info.fans_num) || '',
                level: item.level || (item.author_info && item.author_info.level) || ''
              },
              video_basic: {
                id: item.video_id || item.id || (item.video_basic && item.video_basic.id) || '',
                title: item.title || item.desc || (item.video_basic && item.video_basic.title) || '',
                url: item.url || item.video_url || (item.video_basic && item.video_basic.url) || '',
                cover: item.cover || item.video_cover || item.thumbnail || (item.video_basic && item.video_basic.cover) || '',
                likes: item.like_count || item.likes || (item.video_basic && item.video_basic.likes) || '',
                page_views: item.play_count || item.view_count || item.views || (item.video_basic && item.video_basic.page_views) || '',
                time_range_views: item.time_range_views || (item.video_basic && item.video_basic.time_range_views) || '',
                gmv_range: item.gmv_range || (item.video_basic && item.video_basic.gmv_range) || '',
                sales_range: item.sales_range || (item.video_basic && item.video_basic.sales_range) || '',
                publish_time: item.publish_time || (item.video_basic && item.video_basic.publish_time) || ''
              },
              _original: item
            };
            allVideoList.push(videoObj);
            pageStats[page].extracted += 1;
          });
        } else {
          console.log(`页码 ${page} 未发现可用视频数组，原始结构如下:`);
          try { console.log(JSON.stringify(pageData.data, null, 2)); } catch(e) { console.log(pageData.data); }
        }
      } catch (error) {
        console.error(`处理页码 ${pageData.page || "未知"} 数据出错:`, error);
      }
    });
    console.log("各页码数据统计:");
    Object.keys(pageStats).sort((a, b) => { if (a === "未知") return 1; if (b === "未知") return -1; return parseInt(a) - parseInt(b); }).forEach(page => {
      console.log(`页码 ${page}: 总请求 ${pageStats[page].total} 条，提取视频数据 ${pageStats[page].extracted} 条`);
    });
    console.log(`共提取到 ${allVideoList.length} 条视频数据`);
    
    // 根据video_basic.id进行去重
    const uniqueVideoList = [];
    const seenVideoIds = new Set();
    let duplicateCount = 0;
    
    allVideoList.forEach((video, index) => {
      const videoId = video.video_basic && video.video_basic.id ? video.video_basic.id : '';
      
      if (videoId && !seenVideoIds.has(videoId)) {
        // 首次出现的视频ID，添加到去重列表
        seenVideoIds.add(videoId);
        uniqueVideoList.push(video);
      } else if (videoId) {
        // 重复的视频ID
        duplicateCount++;
        console.log(`JSON导出：发现重复视频ID: ${videoId}，页码: ${video.page}，跳过`);
      } else {
        // 没有视频ID的情况，也添加到列表（可能是数据异常）
        console.log(`JSON导出：视频数据缺少ID字段，页码: ${video.page}，索引: ${index}`);
        uniqueVideoList.push(video);
      }
    });
    
    console.log(`JSON导出去重完成：原始数据 ${allVideoList.length} 条，去重后 ${uniqueVideoList.length} 条，重复 ${duplicateCount} 条`);
    
    if (allVideoList.length === 0) {
      console.log('未提取到视频列表数据，导出原始JSON');
      try {
        const jsonString = JSON.stringify(fixedData, null, 2);
        const blob = new Blob([jsonString], {type: 'application/json'});
        const url = URL.createObjectURL(blob);
        const link = document.createElement('a');
        link.href = url;
        link.download = `抖音视频数据_原始_${new Date().toISOString().slice(0, 10)}.json`;
        document.body.appendChild(link);
        link.click();
        setTimeout(() => { document.body.removeChild(link); URL.revokeObjectURL(url); }, 100);
        return;
      } catch (error) {
        console.error("导出原始JSON失败:", error);
        alert("导出原始JSON失败: " + error.message);
        return;
      }
    }
    try {
      console.log("开始导出合并JSON...");
      const mergedJsonString = JSON.stringify(uniqueVideoList, null, 2);
      const jsonBlob = new Blob([mergedJsonString], {type: 'application/json'});
      const jsonUrl = URL.createObjectURL(jsonBlob);
      const jsonLink = document.createElement('a');
      jsonLink.href = jsonUrl;
      jsonLink.download = `抖音视频数据_合并_${new Date().toISOString().slice(0, 10)}.json`;
      document.body.appendChild(jsonLink);
      jsonLink.click();
      setTimeout(() => { try { document.body.removeChild(jsonLink); URL.revokeObjectURL(jsonUrl); console.log("合并JSON导出完成"); } catch (e) { console.error("清理JSON下载资源出错:", e); } }, 500);
    } catch (error) {
      console.error("导出合并JSON失败:", error);
      alert("导出合并JSON失败: " + error.message);
    }
    try {
      console.log("开始导出文本文件...");
      setTimeout(() => { exportToTextFile(uniqueVideoList); }, 1000);
    } catch (error) {
      console.error("触发导出文本文件失败:", error);
    }
    console.log(`处理完成 ${uniqueVideoList.length} 条视频数据（去重后）`);
  } catch (error) {
    console.error("导出过程中发生错误:", error);
    alert("导出过程中发生错误: " + error.message);
  }
}

// 导出纯文本文件，每行一个完整的JSON对象
function exportToTextFile(videoList) {
  console.log("开始导出纯文本文件，数据条数:", videoList.length);
  
  try {
    // 根据video_basic.id进行去重
    const uniqueVideos = [];
    const seenVideoIds = new Set();
    let duplicateCount = 0;
    
    videoList.forEach((video, index) => {
      const videoId = video.video_basic && video.video_basic.id ? video.video_basic.id : '';
      
      if (videoId && !seenVideoIds.has(videoId)) {
        // 首次出现的视频ID，添加到去重列表
        seenVideoIds.add(videoId);
        uniqueVideos.push(video);
      } else if (videoId) {
        // 重复的视频ID
        duplicateCount++;
        console.log(`文本导出：发现重复视频ID: ${videoId}，页码: ${video.page}，跳过`);
      } else {
        // 没有视频ID的情况，也添加到列表（可能是数据异常）
        console.log(`文本导出：视频数据缺少ID字段，页码: ${video.page}，索引: ${index}`);
        uniqueVideos.push(video);
      }
    });
    
    console.log(`文本导出去重完成：原始数据 ${videoList.length} 条，去重后 ${uniqueVideos.length} 条，重复 ${duplicateCount} 条`);
    
    // 按页码分组去重后的数据
    const groupedByPage = {};
    uniqueVideos.forEach((video, index) => {
      try {
        const page = video.page || "未知页码";
        if (!groupedByPage[page]) {
          groupedByPage[page] = [];
        }
        groupedByPage[page].push(video);
        
        // 每200条记录输出一次日志
        if (index % 200 === 0) {
          console.log(`文本文件：处理了 ${index + 1}/${videoList.length} 条数据`);
        }
      } catch (e) {
        console.error(`分组数据时出错 [${index}]:`, e);
      }
    });
    
    // 创建文本内容
    console.log("开始生成文本内容...");
    let textContent = "";
    
    // 添加页码分隔和数据
    Object.keys(groupedByPage).sort((a, b) => parseInt(a) - parseInt(b)).forEach(page => {
      try {
        const videos = groupedByPage[page];
        textContent += `====== 页码 ${page} (${videos.length} 条数据) ======\n\n`;
        
        videos.forEach((video, index) => {
          try {
            textContent += JSON.stringify(video, null, 2);
            textContent += "\n\n";  // 每个视频之间添加空行
          } catch (e) {
            console.error(`序列化视频数据出错 [页码 ${page}, 索引 ${index}]:`, e);
            textContent += `[错误的JSON数据 - 无法序列化]\n\n`;
          }
        });
        
        textContent += "\n\n";  // 每页之间添加更多空行
      } catch (e) {
        console.error(`处理页码 ${page} 文本内容时出错:`, e);
      }
    });
    
    console.log(`文本内容生成完成，总长度: ${textContent.length} 字符`);
    
    // 创建Blob对象
    const blob = new Blob([textContent], {type: 'text/plain;charset=utf-8'});
    const url = URL.createObjectURL(blob);
    
    // 使用触发下载的方法
    try {
      console.log("创建文本文件下载链接...");
      const link = document.createElement('a');
      link.href = url;
      link.download = `抖音视频数据_完整文本_${new Date().toISOString().slice(0, 10)}.txt`;
      document.body.appendChild(link);
      console.log("触发文本文件下载...");
      link.click();
      
      setTimeout(() => {
        try {
          document.body.removeChild(link);
          URL.revokeObjectURL(url);
          console.log("文本文件导出完成，资源已清理");
        } catch (e) {
          console.error("清理文本下载资源出错:", e);
        }
        
        // 3. 延迟导出Excel格式
        setTimeout(() => {
          try {
            console.log("开始导出Excel格式...");
            exportToSimpleTable(uniqueVideos);
          } catch (error) {
            console.error("导出Excel格式失败:", error);
            alert("导出Excel格式失败: " + error.message);
          }
        }, 1000);
      }, 500);
    } catch (error) {
      console.error("触发文本文件下载失败:", error);
      alert("触发文本文件下载失败: " + error.message);
      
      // 即使文本导出失败，也尝试导出Excel
      setTimeout(() => {
        try {
          exportToSimpleTable(videoList);
        } catch (error) {
          console.error("文本导出失败后尝试导出Excel也失败:", error);
        }
      }, 500);
    }
  } catch (error) {
    console.error("导出纯文本文件失败:", error);
    alert("导出纯文本文件失败: " + error.message);
    
    // 尝试直接导出Excel
    setTimeout(() => {
      try {
        exportToSimpleTable(videoList);
      } catch (error) {
        console.error("文本导出失败后尝试导出Excel也失败:", error);
      }
    }, 500);
  }
}

// 新增：处理数字范围的函数
function parseRangeValue(rangeStr) {
  if (!rangeStr || typeof rangeStr !== 'string') return { original: rangeStr || '', min: '', max: '' };
  
  try {
    // 处理类似 "1万-2万" 或 "1-2万" 的情况
    const hasWan = rangeStr.includes('万');
    // 移除所有空格
    rangeStr = rangeStr.replace(/\s+/g, '');
    
    // 尝试分割范围
    let [min, max] = rangeStr.split('-');
    if (!min || !max) {
      return { original: rangeStr, min: '', max: '' };
    }
    
    // 处理"万"字
    const multiplier = hasWan ? 10000 : 1;
    
    // 清理"万"字，准备转换为数字
    min = min.replace('万', '');
    max = max.replace('万', '');
    
    // 转换为数字
    const minNum = parseFloat(min) * multiplier;
    const maxNum = parseFloat(max) * multiplier;
    
    // 检查转换结果是否有效
    if (isNaN(minNum) || isNaN(maxNum)) {
      return { original: rangeStr, min: '', max: '' };
    }
    
    return {
      original: rangeStr,
      min: minNum,
      max: maxNum
    };
  } catch (e) {
    console.error('解析范围值出错:', e);
    return { original: rangeStr, min: '', max: '' };
  }
}

function exportToSimpleTable(videoList) {
  console.log("开始导出简单表格...");
  
  try {
    // 根据video_basic.id进行去重
    const uniqueVideos = [];
    const seenVideoIds = new Set();
    let duplicateCount = 0;
    
    videoList.forEach((video, index) => {
      const videoId = video.video_basic && video.video_basic.id ? video.video_basic.id : '';
      
      if (videoId && !seenVideoIds.has(videoId)) {
        // 首次出现的视频ID，添加到去重列表
        seenVideoIds.add(videoId);
        uniqueVideos.push(video);
      } else if (videoId) {
        // 重复的视频ID
        duplicateCount++;
        console.log(`Excel导出：发现重复视频ID: ${videoId}，页码: ${video.page}，跳过`);
      } else {
        // 没有视频ID的情况，也添加到列表（可能是数据异常）
        console.log(`Excel导出：视频数据缺少ID字段，页码: ${video.page}，索引: ${index}`);
        uniqueVideos.push(video);
      }
    });
    
    console.log(`Excel导出去重完成：原始数据 ${videoList.length} 条，去重后 ${uniqueVideos.length} 条，重复 ${duplicateCount} 条`);
    
    // 准备CSV内容
    let csvContent = "\ufeff"; // BOM头，防止中文乱码
    // 表头
    const headers = [
      "页码", "视频ID", "视频标题", "作者昵称", "作者头像", "作者等级", "作者粉丝数",
      "点赞数", "播放量", "时段播放量", "视频时长", "是否优质视频",
      "GMV范围_原始值", "GMV范围_最小值", "GMV范围_最大值",
      "销量范围_原始值", "销量范围_最小值", "销量范围_最大值",
      "发布时间", "视频链接", "视频封面", "抖音视频地址", "产品ID", "推广ID", "产品名称", "产品封面",
      "客单价", "万播转化", "GPM"
    ];
    csvContent += headers.map(h => `"${h}"`).join(",") + "\n";
    
    // 遍历去重后的视频数据
    uniqueVideos.forEach((video, index) => {
      try {
        // 提取基础数据
        const page = video.page || "";
        const videoId = video.video_basic && video.video_basic.id ? video.video_basic.id : "";
        const title = video.video_basic && video.video_basic.title ? video.video_basic.title.replace(/"/g, '""') : "";
        
        // 作者信息
        const authorNickName = video.author_info && video.author_info.nick_name ? video.author_info.nick_name.replace(/"/g, '""') : "";
        const authorCover = video.author_info && video.author_info.cover ? video.author_info.cover : "";
        const authorLevel = video.author_info && video.author_info.level ? video.author_info.level : "";
        const fansNum = video.author_info && video.author_info.fans_num ? video.author_info.fans_num : "";
        
        // 视频基础数据
        let likes = "", pageViews = "", timeRangeViews = "", duration = "", isGreatVideo = "";
        let gmvRange = "", salesRange = "";
        
        try {
          likes = video.video_basic && video.video_basic.likes ? video.video_basic.likes : "";
          pageViews = video.video_basic && video.video_basic.page_views ? video.video_basic.page_views : "";
          timeRangeViews = video.video_basic && video.video_basic.time_range_views ? video.video_basic.time_range_views : "";
          duration = video.video_basic && video.video_basic.duration ? video.video_basic.duration : "";
          isGreatVideo = video.video_basic && video.video_basic.is_great_video !== undefined ? video.video_basic.is_great_video.toString() : "";
          gmvRange = video.video_basic && video.video_basic.gmv_range ? video.video_basic.gmv_range : "";
          salesRange = video.video_basic && video.video_basic.sales_range ? video.video_basic.sales_range : "";
        } catch (e) {
          console.error("处理视频基础数据出错:", e);
        }
        
        // 处理GMV范围和销量范围
        const gmvRangeData = parseRangeValue(gmvRange);
        const salesRangeData = parseRangeValue(salesRange);
        
        // 发布时间
        let publishTime = "";
        try {
          if (video.video_basic && video.video_basic.publish_time) {
            const timestamp = video.video_basic.publish_time;
            if (typeof timestamp === 'number' || !isNaN(parseInt(timestamp))) {
              try {
                const date = new Date(parseInt(timestamp) * 1000);
                publishTime = date.toISOString().replace('T', ' ').substring(0, 19);
              } catch (e) {
                publishTime = timestamp.toString();
              }
            } else {
              publishTime = timestamp.toString();
            }
          }
        } catch (e) {
          console.error("处理发布时间出错:", e);
        }
        
        // 视频链接和封面图
        const videoUrl = video.video_basic && video.video_basic.url ? video.video_basic.url : "";
        const coverUrl = video.video_basic && video.video_basic.cover ? video.video_basic.cover : "";
        
        // 产品信息 - 优先从_original中获取，备选方案是video_basic
        let productId = "", promotionId = "", productName = "", productCover = "";
        try {
          let productList = null;
          
          // 优先尝试从_original.video_basic.product_list获取
          if (video._original && video._original.video_basic && video._original.video_basic.product_list && video._original.video_basic.product_list.length > 0) {
            productList = video._original.video_basic.product_list;
          }
          // 备选方案：从video_basic.product_list获取
          else if (video.video_basic && video.video_basic.product_list && video.video_basic.product_list.length > 0) {
            productList = video.video_basic.product_list;
          }
          
          if (productList && productList.length > 0) {
            const product = productList[0]; // 取第一个产品
            productId = product.product_id || "";
            promotionId = product.promotion_id || "";
            productName = product.name ? product.name.replace(/"/g, '""') : "";
            productCover = product.cover || "";
          }
        } catch (e) {
          console.error("处理产品信息出错:", e);
        }
        
        // 计算抖音视频地址
        const douyinVideoUrl = videoId ? `https://www.douyin.com/video/${videoId}` : "";
        
        // 计算商业指标
        let unitPrice = "", wanBoConversion = "", gpm = "";
        try {
          const gmvMax = gmvRangeData.max || 0;
          const salesMax = salesRangeData.max || 0;
          const pageViewsNum = parseFloat(pageViews) || 0;
          
          // 客单价 = GMV范围_最大值 / 销量范围_最大值
          if (salesMax > 0) {
            unitPrice = (gmvMax / salesMax).toFixed(2);
          }
          
          // 万播转化 = 销量范围_最大值 / 播放量 * 10000
          if (pageViewsNum > 0) {
            wanBoConversion = ((salesMax / pageViewsNum) * 10000).toFixed(4);
          }
          
          // GPM = GMV范围_最大值 / 播放量 * 1000
          if (pageViewsNum > 0) {
            gpm = ((gmvMax / pageViewsNum) * 1000).toFixed(2);
          }
        } catch (e) {
          console.error("计算商业指标出错:", e);
        }
        
        // 组装行数据
        const row = [
          page,
          videoId,
          title,
          authorNickName,
          authorCover,
          authorLevel,
          fansNum,
          likes,
          pageViews,
          timeRangeViews,
          duration,
          isGreatVideo,
          gmvRangeData.original,
          gmvRangeData.min,
          gmvRangeData.max,
          salesRangeData.original,
          salesRangeData.min,
          salesRangeData.max,
          publishTime,
          videoUrl,
          coverUrl,
          douyinVideoUrl,
          productId,
          promotionId,
          productName,
          productCover,
          unitPrice,
          wanBoConversion,
          gpm
        ];
        
        // 添加到CSV内容
        csvContent += row.map(field => `"${field}"`).join(",") + "\n";
        
      } catch (error) {
        console.error(`处理视频数据出错 [${index}]:`, error);
      }
    });
    
    // 使用Blob方式，兼容大文件
    const blob = new Blob([csvContent], { type: 'text/csv;charset=utf-8;' });
    const url = URL.createObjectURL(blob);
    const link = document.createElement("a");
    link.setAttribute("href", url);
    link.setAttribute("download", `抖音视频数据_${new Date().toISOString().slice(0, 10)}.csv`);
    document.body.appendChild(link);
    link.click();
    setTimeout(() => {
      document.body.removeChild(link);
      URL.revokeObjectURL(url);
    }, 100);
    
  } catch (error) {
    console.error("导出CSV失败:", error);
    alert("导出CSV失败: " + error.message);
  }
} 